package com.app.utils.base.j2se;


import java.lang.reflect.Field;
import java.lang.reflect.Method;

public class PropertyFieldDescriptor
{
  private Class<?> propertyType;
  private Method readMethod;
  private Method writeMethod;
  private Field field;
  private String propertyName;

  public Class<?> getPropertyType()
  {
    return this.propertyType;
  }

  public String getPropertyName() {
    return this.propertyName;
  }

  public PropertyFieldDescriptor(Field field) {
    this.readMethod = null;
    this.writeMethod = null;
    this.field = field;
    this.propertyName = field.getName();
    this.propertyType = field.getType(); }

  public PropertyFieldDescriptor(String propertyName, Method readMethod, Method writeMethod) {
    this.readMethod = readMethod;
    this.writeMethod = writeMethod;
    this.field = null;
    this.propertyName = propertyName;
    this.propertyType = readMethod.getReturnType(); }

  public PropertyFieldDescriptor(Method readMethod, Field field) {
    this.readMethod = readMethod;
    this.writeMethod = null;
    this.field = field;
    this.propertyName = field.getName();
    this.propertyType = field.getType(); }

  public PropertyFieldDescriptor(Field field, Method writeMethod) {
    this.readMethod = null;
    this.writeMethod = writeMethod;
    this.field = field;
    this.propertyName = field.getName();
    this.propertyType = field.getType(); }

  public Object get(Object obj) {
    try {
      if (this.readMethod != null) {
        return this.readMethod.invoke(obj, new Object[0]);
      }

      return this.field.get(obj);
    }
    catch (Exception e)
    {
    }

    return null; }

  public void set(Object obj, Object value) {
    try {
      Object prop = PropertyFieldUtils.coverTo(value, this.propertyType);
      if (this.writeMethod != null) {
        this.writeMethod.invoke(obj, new Object[] { prop });
      }
      else if (this.field != null)
      {
        this.field.set(obj, prop);
      }
      else throw new RuntimeException("Property protected!");
    }
    catch (Exception e) {
      throw new RuntimeException(e);
    }
  }
}